/**
 * Copyright (c) 2009 Teoti Graphix, LLC See:
 *     hhttp://tkarchitecture.teotigraphix.org
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 * 
 * @author Michael Schmalle mschmalle@teotigraphix.com
 */
package org.example.ui.behavior
{

import flash.events.IEventDispatcher;

import mx.core.IFactory;
import mx.core.IVisualElement;
import mx.styles.IStyleClient;

import org.teotigraphix.dx.patterns.manager.StyleBindingManager;
import org.teotigraphix.tka.patterns.behavior.SparkComponentBehavior;

/**
 * 
 */
[Style(name="iconPlacement", type="String")]
[Style(name="iconPlacementFunction", type="Function")]

/**
 * A behavior that adds iconPlacement functionality to a spark button component.
 * 
 * <p>This IComponentBehavior implementation </p>
 * 
 * @author Michael Schmalle 
 */
public class IconBehavior 
	   extends SparkComponentBehavior 
	   implements IIconBehavior
{
	//--------------------------------------------------------------------------
	//
	//  SkinPartAlias :: Varaibles
	//
	//--------------------------------------------------------------------------
	
	[SkinPartAlias]
	
	/**
	 * The icon display component.
	 */
	public var iconDisplay:IVisualElement;	
	
	//--------------------------------------------------------------------------
	//
	//  Constructor
	//
	//--------------------------------------------------------------------------
	
	/**
	 * Constructor.
	 */
	public function IconBehavior()
	{
		super();
	}
	
	//--------------------------------------------------------------------------
	//
	//  Overridden Protected :: Methods
	//
	//--------------------------------------------------------------------------
	
	/**
	 * @private
	 * Runs when registerBehavior() is called.
	 */
	override protected function setComponent(hostComponent:IEventDispatcher):void
	{
		super.setComponent(hostComponent);
		
		//commitIcon();
		commitIconPlacement();
	}
	
	/**
	 * @private
	 */
	override protected function partAdded(partName:String, instance:Object):void
	{
		super.partAdded(partName, instance);
		
		if (instance == iconDisplay)
		{
			commitIcon();
		}
	}
	
	/**
	 * @private
	 */
	override protected function partRemoved(partName:String, instance:Object):void
	{
		super.partRemoved(partName, instance);
		
		if (instance == iconDisplay)
		{
		}
	}	
	
	//--------------------------------------------------------------------------
	//
	//  Protected :: Methods
	//
	//--------------------------------------------------------------------------
	
	/**
	 * Commits the icon source to the iconDisplay component.
	 */
	protected function commitIcon():void
	{
		if (!iconDisplay)
			return;
		
		var icon:Class;
		if ("icon" in component)
			icon = Object(component).icon;
		if (icon == null)
			icon = IStyleClient(component).getStyle("icon");		
		
		// IDataRenderer.data.icon could be checked as well
		
		if ("source" in iconDisplay)
			Object(iconDisplay).source = icon;
		
		//iconDisplay.includeInLayout = visible;
		//iconDisplay.visible = visible;
		
		StyleBindingManager.initialize(Object(component).skin, component as IStyleClient);
	}
	
	/**
	 * Commits the icon source to the iconDisplay component.
	 */
	protected function commitIconPlacement():void
	{
		var placement:String;
		// if the component has a label placement property
		if ("iconPlacement" in component)
			placement = Object(component).iconPlacement;
		// if the component has the style
		if (placement == null)
			placement = IStyleClient(component).getStyle("iconPlacement");
		
		// IDataRenderer.data.iconPlacement could be checked as well
		
		// default
		if (placement == null)
			placement = "left";
		
		var client:IStyleClient = component as IStyleClient;
		
		// the the component has a label placement function
		var pfunction:Function = client.getStyle("iconPlacementFunction");
		if (pfunction == null)
			pfunction = defaultLabelPlacementFunction;
		
		// st the skin factory
		var factory:IFactory = pfunction(placement);
		if (factory)
			client.setStyle("skinFactory", factory);
	}
	
	/**
	 * @private
	 */
	protected function defaultLabelPlacementFunction(placement:String):IFactory
	{
		throw new Error("Subclass of IconBehavior must implement defaultLabelPlacementFunction()");
	}	
}
}